package com.ichengzi.audit.human.repository.mysql.service;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.keywords.MySqlKeyWordsHandler;
import com.ichengzi.audit.human.repository.mysql.utils.FileUtil;
import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

import java.nio.charset.StandardCharsets;

/**
 *
 * 代码生成器
 * @author lihn
 */
@Data
@Service("codeGeneratorService")
public class CodeGeneratorService {
    /** 生成代码暂存目录 */
    private static final String TMP_PATH = "mybatis_generator_path";
    /** 数据库 */
    @Value("${spring.datasource.url}")
    private String jdbcUrl;
    @Value("${spring.datasource.username}")
    private String jdbcUserName;
    @Value("${spring.datasource.password}")
    private String jdbcPassword;

    /**
     * mybatis自动生成代码
     * @param tables 要生成代码的表，多个以逗号隔开
     * @return 生成的压缩包路径
     */
    public String generator(String tables) {
        String outputPathURL = FileUtil.class.getClassLoader().getResource("").getPath() + TMP_PATH;
        String outputPath;
        try {
            // 中文路径处理
            outputPath = URLDecoder.decode(outputPathURL, String.valueOf(StandardCharsets.UTF_8));
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        // 1.数据库配置
        DataSourceConfig.Builder dataSourceConfigBuilder =
                new DataSourceConfig.Builder(getJdbcUrl(), getJdbcUserName(), getJdbcPassword())
                .dbQuery(new MySqlQuery()).typeConvert(new MySqlTypeConvert())
                .keyWordsHandler(new MySqlKeyWordsHandler());
        // 表名，多个表使用英文逗号分割
        String[] tableNames = tables.split(",");
        // 1.1.快速生成器
        FastAutoGenerator fastAutoGenerator = FastAutoGenerator.create(dataSourceConfigBuilder);

        // 2.全局配置
        fastAutoGenerator.globalConfig(globalConfigBuilder -> globalConfigBuilder.fileOverride().disableOpenDir()
                .outputDir(outputPath).author("mybatis-plus generator").commentDate("yyyy-MM-dd").dateType(DateType.TIME_PACK));

        // 3.包配置
//        fastAutoGenerator.packageConfig(packageConfigBuilder -> packageConfigBuilder
//                .parent("").moduleName("")
//                .entity("entity").mapper("dao")
//                .pathInfo(new HashMap<OutputFile, String>(2) {{
//                              put(OutputFile.entity, "audit-human-core/audit-human-core-live/src/main/java/com/ichengzi/audit/human/core/live/mybatis/domain");
//                              put(OutputFile.mapper, "audit-human-core/audit-human-core-live/src/main/java/com/ichengzi/audit/human/core/live/mybatis/mapper");
//                              put(OutputFile.xml, "audit-human-core/audit-human-core-live/src/main/resources/mapper");
//                          }}));

        // 4.模板配置
        // 使用Freemarker引擎模板，默认的是Velocity引擎模板
        AbstractTemplateEngine templateEngine = new FreemarkerTemplateEngine();
        fastAutoGenerator.templateEngine(templateEngine);

        // 6.策略配置
        // 设置需要生成的表名
        fastAutoGenerator.strategyConfig(strategyConfigBuilder -> strategyConfigBuilder.enableCapitalMode()
                .enableSkipView().disableSqlFilter().addInclude(tableNames));

        // 6.1.Entity策略配置
        fastAutoGenerator.strategyConfig(strategyConfigBuilder -> strategyConfigBuilder.entityBuilder()
                .enableTableFieldAnnotation().naming(NamingStrategy.underline_to_camel).enableLombok()
                .columnNaming(NamingStrategy.underline_to_camel).idType(IdType.NONE).formatFileName("%sEntity"));

        // 6.2.Controller策略配置
        fastAutoGenerator
                .strategyConfig(strategyConfigBuilder -> strategyConfigBuilder.controllerBuilder().enableRestStyle());

        // 6.3.Service策略配置
        // 格式化service接口和实现类的文件名称，去掉默认的ServiceName前面的I
        fastAutoGenerator.strategyConfig(strategyConfigBuilder -> strategyConfigBuilder.serviceBuilder()
                .formatServiceFileName("%sService").formatServiceImplFileName("%sServiceImpl"));

        // 6.4.Mapper策略配置
        // 格式化 mapper文件名,格式化xml实现类文件名称
        fastAutoGenerator.strategyConfig(strategyConfigBuilder -> strategyConfigBuilder.mapperBuilder()
                .formatMapperFileName("%sDao").formatXmlFileName("%sDao"));

        // 7.生成代码
        fastAutoGenerator.execute();

        return FileUtil.zip(outputPath);
    }



}
